package com.lplb.common.coreconfig.config.Init.config;


import com.lplb.api.admin.model.dto.AdminAuthDTO;
import com.lplb.common.core.constant.base.BaseConstant;
import com.lplb.common.core.utils.ClassUtil;
import com.lplb.common.core.utils.snowflakeId.SnowflakeIdUtils;
import com.lplb.common.coreconfig.feign.RAdminAuthServiceFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

// @Bean
// @PostConstruct
// @PreDestroy

/**
 *
 * @author wangsong
 * @mail 1720696548@qq.com
 * @date 2020/7/23 0023 9:04
 * @version 1.0.0
 */
@Component
@Slf4j
public class CommandLineRunnerImpl implements CommandLineRunner {

    /**
     * 扫包路径
     */
    private static String PACKAGE_NAME = "com.lplb.api";
    /**
     *
     */
    @Autowired(required = false)
    private RAdminAuthServiceFeign rAdminAuthServiceFeign;

    @Value("${spring.application.name}")
    private String serverName;

    @Override
    public void run(String... args) throws Exception {
        List<Class<?>> classByPackageName = ClassUtil.getClasses(PACKAGE_NAME);
        //
        List<String> classRequestMappingList = new ArrayList<>();
        //
        List<AdminAuthDTO> adminAuthDTOList = new ArrayList<>();
        // 遍历所有类
        for (Class<?> classInfo : classByPackageName) {
            // 类上存在 @Api 注解 + @RequestMapping 的类进行下一步操作
            Api apiClass = classInfo.getDeclaredAnnotation(Api.class);
            RequestMapping requestMappingClass = classInfo.getDeclaredAnnotation(RequestMapping.class);
            if (apiClass == null || requestMappingClass == null) {
                continue;
            }
            // 判断类注解的RequestMapping参数是否重复
            if (classRequestMappingList.contains(requestMappingClass.value()[0])) {
                try {
                    throw new Throwable(" =====> 类[{" + classInfo.getName() + "}]的 RequestMapping 注解参数与 xxx类发送重复,权限列表更新失败,");
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }
            classRequestMappingList.add(requestMappingClass.value()[0]);
            // 判断当前类是否需要保存到接口权限内（目前：PC_ADMIN=平台 ） 需要
            if (apiClass.description().equals(BaseConstant.Sys.MANAGEMENT_SIDE)) {
                System.out.println("当前类信息-->" + apiClass.value() + "-->" + apiClass.tags()[0] + " --> " + requestMappingClass.value()[0]);
                AdminAuthDTO classAdminAuthDTO = new AdminAuthDTO();
                classAdminAuthDTO.setServerName(serverName);                    // 服务名
                classAdminAuthDTO.setDesc(apiClass.tags()[0]);                  // 接口描叙
                classAdminAuthDTO.setUrl(requestMappingClass.value()[0]);       // 类url
                classAdminAuthDTO.setId(SnowflakeIdUtils.nextId().toString());  // id
                classAdminAuthDTO.setMethod("");                                // 请求方式
                classAdminAuthDTO.setPid("");                                   // 父id
                //
                adminAuthDTOList.add(classAdminAuthDTO);
                // 获取类的所有方法
                Method[] methods = classInfo.getDeclaredMethods();
                //循环添加方法级权限
                for (Method method : methods) {
                    RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                    ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
                    if (requestMapping == null || apiOperation == null) {
                        log.info(method.getDeclaringClass().getName() + "." + method.getName() + "方法没有@ApiOperation 或 @RequestMapping注解");
                        continue;
                    }
                    String url = classAdminAuthDTO.getUrl() + requestMapping.value()[0];
                    AdminAuthDTO methodAdminAuthDTO = new AdminAuthDTO();
                    methodAdminAuthDTO.setServerName(serverName);                       // 服务名
                    methodAdminAuthDTO.setDesc(apiOperation.value());                   // 接口描叙
                    methodAdminAuthDTO.setUrl(url);                                     // 接口url
                    methodAdminAuthDTO.setId(SnowflakeIdUtils.nextId().toString());     // id
                    methodAdminAuthDTO.setMethod(requestMapping.method()[0].name());    // 请求方式
                    methodAdminAuthDTO.setPid(classAdminAuthDTO.getId());               // 父id
                    //
                    adminAuthDTOList.add(methodAdminAuthDTO);
                    log.info("方法:{} URL:{} 请求方式:{} 描叙:{} ", method.getDeclaringClass().getName() + "." + method.getName(), url, requestMapping.method()[0].name(), apiOperation.value());
                }
            }
        }
        rAdminAuthServiceFeign.updList(adminAuthDTOList);
    }
}